package im.yisme.model;

import im.yisme.model.fileio.DirManager;
import im.yisme.model.fileio.LyricsReader;
import im.yisme.model.remote.PostHandler;
import im.yisme.model.service.PlatformService;
import im.yisme.vo.LyricsVO;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;

import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class Platform implements PlatformService{

	private static Platform platform;
	private ArrayList<LyricsVO> searchResult;
	private boolean searching;

	private Platform(){
		
	}
	
	public static Platform getInstance(){
		return platform == null ? platform = new Platform() : platform;
	}
	
	public boolean isSearching() {
		// TODO Auto-generated method stub
		return searching;
	}

	public Iterator<LyricsVO> getSearchResult() {
		// TODO Auto-generated method stub
		return searchResult == null ? null : searchResult.iterator();
	}

	public void search(String keyword) throws IOException, JSONException{
		// TODO Auto-generated method stub
		searching = true;
		
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();	
		params.add(new BasicNameValuePair("keyword", keyword));
		UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF8");
		JSONObject jsonObject = new PostHandler().post(entity, PostHandler.SEARCH_SERVLET);
		JSONArray array = jsonObject.getJSONArray("result");
		
		if (searchResult == null)
			searchResult = new ArrayList<LyricsVO>();
		else
			searchResult.clear();
		
		for (int i=0; i<array.length(); i++){
			JSONObject object = array.getJSONObject(i);
			long remoteId = object.getLong("remoteId");
			String artist = object.getString("artist");
			String name = object.getString("name");
			int score = object.getInt("score");
//			int source = object.getInt("source");
			int source = Lyrics.OFFICIAL;
			searchResult.add(new LyricsVO(remoteId, artist, name, score, source));
		}
		
		searching = false;
	}

	public boolean evaluate(long id, int score) throws IOException, JSONException {
		// TODO Auto-generated method stub
		LyricsRepository lyricsRepository = LyricsRepository.getInstance();
		Lyrics lyrics = lyricsRepository.getLyrics(id);
		
		LyricsReader lyricsReader = new LyricsReader();
		lyricsReader.read(lyrics);
		
		
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();	
		params.add(new BasicNameValuePair("remoteId", lyrics.getRemoteId() + ""));
		params.add(new BasicNameValuePair("score", score + ""));
		UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF8");
		JSONObject jsonObject = new PostHandler().post(entity, PostHandler.EVALUATE_SERVLET);
		return jsonObject.getBoolean("flag");
	}

	public long uploadInfo(long id) throws IOException, JSONException {
		// TODO Auto-generated method stub
		LyricsRepository lyricsRepository = LyricsRepository.getInstance();
		Lyrics lyrics = lyricsRepository.getLyrics(id);
		
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();	
		params.add(new BasicNameValuePair("artist", lyrics.getArtist()));
		params.add(new BasicNameValuePair("name", lyrics.getName()));
		UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF8");
		JSONObject jsonObject = new PostHandler().post(entity, PostHandler.UPLOAD_SERVLET);
		
		long remoteId = jsonObject.getLong("remoteId");		
		
		LyricsReader lyricsReader = new LyricsReader();
		lyricsReader.read(lyrics);
		
		lyrics.setRemoteId(remoteId);
		
		return remoteId;
	}
	
	public boolean uploadFile(long id, long remoteId) throws IOException, JSONException {
		// TODO Auto-generated method stub
		File file = new File(DirManager.getLyricsDir() + id + ".ylrc");	
		
		MultipartEntity mpEntity = new MultipartEntity();
		ContentBody cbFile = new FileBody(file);
		ContentBody cbId = new StringBody(remoteId + "");		
		mpEntity.addPart("file", cbFile);
		mpEntity.addPart("remoteId", cbId);
		
		JSONObject jsonObject = new PostHandler().post(mpEntity, PostHandler.UOLOADFILE_SERVLET);
		return jsonObject.getBoolean("flag");
	}

	public LyricsVO downloadInfo(long remoteId) throws IOException, JSONException {
		// TODO Auto-generated method stub
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();	
		params.add(new BasicNameValuePair("remoteId", remoteId + ""));
		UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF8");
		JSONObject jsonObject = new PostHandler().post(entity, PostHandler.DOWNLOAD_SERVLET);
		String url = jsonObject.getString("url");
		String artist = jsonObject.getString("artist");
		String name = jsonObject.getString("name");
		int source = jsonObject.getInt("source");
		
		LyricsVO lyricsVO = new LyricsVO(0, artist, name, url, source);
		return lyricsVO;
	}

	public void downloadFile(long id, String filePath) throws IOException,
			JSONException {
		// TODO Auto-generated method stub
		File dir = new File(DirManager.getLyricsDir());
		if (!dir.exists())
			dir.mkdirs();
		
		File file = new File(DirManager.getLyricsDir() + id + ".ylrc");
		OutputStream os = new FileOutputStream(file);
		
		URL url = new URL(filePath);
		InputStream is = url.openStream();
		
		byte[] buff = new byte[1024];
		while(true) {
			int readed = is.read(buff);
			if(readed == -1) {
				break;
			}
			byte[] temp = new byte[readed];
			System.arraycopy(buff, 0, temp, 0, readed);
			os.write(temp);
		}
		is.close(); 
        os.close();
	}

}
